package com.ygqh.baby.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.ygqh.baby.ao.CheckStatus;
import com.ygqh.baby.ao.CommentType;
import com.ygqh.baby.ao.DataStatus;
import com.ygqh.baby.ao.QueryInfo;
import com.ygqh.baby.ao.ResultSet;
import com.ygqh.baby.mapper.YgPublishCommentMapper;
import com.ygqh.baby.mapper.YgPublishDetailMapper;
import com.ygqh.baby.mapper.YgPublishDetailTagMapper;
import com.ygqh.baby.mapper.YgPublishMapper;
import com.ygqh.baby.model.YgIndexCommentModel;
import com.ygqh.baby.model.YgIndexModel;
import com.ygqh.baby.model.YgNotSaleHeadModel;
import com.ygqh.baby.model.YgSimilarityPublishModel;
import com.ygqh.baby.po.YgProduct;
import com.ygqh.baby.po.YgPublish;
import com.ygqh.baby.po.YgPublishComment;
import com.ygqh.baby.po.YgPublishDetail;
import com.ygqh.baby.po.YgPublishDetailTag;
import com.ygqh.baby.po.YgPublishExample;
import com.ygqh.baby.service.YgProductService;
import com.ygqh.baby.service.YgPublishCommentService;
import com.ygqh.baby.service.YgPublishService;
import com.ygqh.baby.service.YgSkuService;

@Service
public class YgPublishServiceImpl implements YgPublishService {

	private Logger logger = Logger.getLogger(YgPublishServiceImpl.class);

	static final Integer MAX_PUBLISH_COUNT = 10;
	@Autowired
	private YgPublishMapper ygPublishMapper;
	@Autowired
	private YgPublishCommentService commentService;
	@Autowired
	private YgSkuService skuService;
	@Autowired
	private YgProductService productService;
	@Autowired
	private YgPublishDetailTagMapper publishDetailTagMapper;
	@Autowired
	private YgPublishDetailMapper publishDetailMapper;
	@Autowired
	private YgPublishCommentMapper publishCommentMapper;
	@Autowired
	private SensitivewordFilter sensitivewordFilter;
	@Autowired
	private YgPublishCommentService publishCommentService;

	@Override
	public List<YgPublish> find() {
		YgPublishExample example = new YgPublishExample();
		example.createCriteria().andStatusNotEqualTo(DataStatus.Delete.name());
		return ygPublishMapper.selectByExample(example);
	}

	@Override
	public int findCount() {
		YgPublishExample example = new YgPublishExample();
		example.createCriteria().andStatusNotEqualTo(DataStatus.Delete.name());
		return ygPublishMapper.countByExample(example);
	}

	@Override
	public YgPublish findById(Long id) {
		return ygPublishMapper.selectByPrimaryKey(id);
	}

	@Override
	public int save(YgPublish ygPublish, List<YgPublishDetail> publishDetailList) {

		int r = ygPublishMapper.insertSelective(ygPublish);
		List<YgPublishDetailTag> publishDetailTags = new ArrayList<YgPublishDetailTag>();
		for (YgPublishDetail detail : publishDetailList) {
			detail.setPublishId(ygPublish.getId());
			detail.setStatus(DataStatus.Valid);
			publishDetailMapper.insert(detail);
			for (YgPublishDetailTag tag : detail.getPublishDetailTags()) {
				tag.setPdId(detail.getId());
				publishDetailTags.add(tag);
			}
		}
		if (CollectionUtils.isNotEmpty(publishDetailTags)) {
			ygPublishMapper.insertBatchPublishDetailTags(publishDetailTags);
		}
		return ygPublish.getId().intValue();
	}

	@Override
	public int update(YgPublish ygPublish) {
		return ygPublishMapper.updateByPrimaryKeySelective(ygPublish);
	}

	@Override
	public ResultSet<YgPublish> search(QueryInfo queryInfo, String q, String sortField, String sort, String checkStatus, Date startTime, Date endTime, Long id,
			String userName) {
		List<YgPublish> list = ygPublishMapper.selectSuper(queryInfo, q, sortField, sort, checkStatus, startTime, endTime, id, userName);
		int count = ygPublishMapper.countSuper(q, sortField, sort, checkStatus, startTime, endTime, id, userName);

		ResultSet<YgPublish> resultSet = new ResultSet<YgPublish>(count, list);
		return resultSet;
	}

	@Override
	public int deleteSoft(Long[] ids) {
		Assert.notEmpty(ids);
		int count = 0;
		for (Long id : ids) {
			YgPublish ygPublish = this.findById(id);
			ygPublish.setStatus(DataStatus.Delete);
			count += ygPublishMapper.updateByPrimaryKeySelective(ygPublish);
		}

		return count;
	}

	@Override
	public int deleteSoft(Long id) {
		return this.deleteSoft(new Long[] { id });
	}

	@Deprecated
	@Override
	public ResultSet<YgIndexModel> searchModel4Index(QueryInfo queryInfo) {
		List<YgIndexModel> list = ygPublishMapper.selectModel4Index(queryInfo, new HashMap<String, Object>());
		int count = ygPublishMapper.selectModel4IndexCount();
		ResultSet<YgIndexModel> resultSet = new ResultSet<YgIndexModel>(count, list);
		return resultSet;
	}

	@Override
	public YgIndexModel findDetailModel(Long id) {
		return ygPublishMapper.findDetailModel(id);
	}

	@Override
	public ResultSet<YgIndexModel> searchModel4User(QueryInfo queryInfo, Long userId) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("userId", userId);
		List<YgIndexModel> list = ygPublishMapper.selectModel4User(queryInfo, params);
		int count = ygPublishMapper.selectModel4UserCount(params);
		ResultSet<YgIndexModel> resultSet = new ResultSet<YgIndexModel>(count, list);
		return resultSet;
	}

	@Override
	public ResultSet<YgIndexModel> searchModel4Praise(QueryInfo queryInfo, Long userId) {
		Long[] publishIds = commentService.findPublishIdsByUser(userId);
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("publishIds", publishIds);
		int count = ygPublishMapper.selectModel4PublishCount(params);
		List<YgIndexModel> list = ygPublishMapper.selectModel4Publish(queryInfo, params);
		ResultSet<YgIndexModel> resultSet = new ResultSet<YgIndexModel>(count, list);
		return resultSet;
	}

	@Override
	public YgNotSaleHeadModel findNotSaleHeadModel(Long pdtId) {
		return ygPublishMapper.findNotSaleHeadModel(pdtId);
	}

	@Cacheable(cacheNames = "redis", key = "'publish:similarity_'+#groupId+'_'+#productId")
	@Override
	public List<YgSimilarityPublishModel> findSimilarityPublishModel(Long productId, Long groupId, Long excludePublishId) {

		List<YgSimilarityPublishModel> result = new ArrayList<YgSimilarityPublishModel>();
		similarityStep1(result, productId, excludePublishId);
		similarityStep2(result, groupId, excludePublishId);
		similarityStep3(result, productId, excludePublishId);
		similarityStep4(result, excludePublishId);

		return result;
	}

	@Override
	public List<YgSimilarityPublishModel> similarityPublish4NotSale(String brandName, String categoryId, Long excludePublishId) {
		// 同品牌同分类
		List<YgSimilarityPublishModel> step1 = ygPublishMapper.findSimilarityPublishEqualCategory4NotSale(brandName, categoryId);

		if (step1.size() >= MAX_PUBLISH_COUNT) {
			return step1;
		}
		// 同品牌不同分类
		List<YgSimilarityPublishModel> step2 = ygPublishMapper.findSimilarityPublishNoEqualCategory4NotSale(brandName, categoryId);
		setData(step2, step1, excludePublishId);
		if (step1.size() >= MAX_PUBLISH_COUNT) {
			return step1;
		}

		similarityStep4(step1, excludePublishId);
		return step1;
	}

	private void setData(List<YgSimilarityPublishModel> dataBaseList, List<YgSimilarityPublishModel> result, Long excludePublishId) {
		for (YgSimilarityPublishModel model : dataBaseList) {
			if (result.size() == MAX_PUBLISH_COUNT)
				return;

			boolean flag = false;
			for (YgSimilarityPublishModel rm : result) {
				if (rm.getPublishId().equals(model.getPublishId())) {
					flag = true;
				}
			}
			if (!flag && !model.getPublishId().equals(excludePublishId))
				result.add(model);
		}
	}

	// 1该商品的晒单
	private void similarityStep1(List<YgSimilarityPublishModel> result, Long productId, Long excludePublishId) {
		List<YgSimilarityPublishModel> dataBaseList = new ArrayList<YgSimilarityPublishModel>();
		dataBaseList = ygPublishMapper.findSimilarityPublishModelByProductId(new Long[] { productId });
		setData(dataBaseList, result, excludePublishId);
	}

	// 2同款商品晒单
	private void similarityStep2(List<YgSimilarityPublishModel> result, Long groupId, Long excludePublishId) {
		List<YgSimilarityPublishModel> dataBaseList = new ArrayList<YgSimilarityPublishModel>();
		List<YgProduct> products = productService.findDetailByGroupId(groupId);
		List<Long> productIds = new ArrayList<Long>();
		for (YgProduct p : products) {
			productIds.add(p.getId());
		}
		if (productIds.isEmpty())
			return;

		dataBaseList = ygPublishMapper.findSimilarityPublishModelByProductId(productIds.toArray(new Long[] {}));

		setData(dataBaseList, result, excludePublishId);
	}

	// 3同品牌同分类
	private void similarityStep3(List<YgSimilarityPublishModel> result, Long productId, Long excludePublishId) {
		List<YgSimilarityPublishModel> dataBaseList = new ArrayList<YgSimilarityPublishModel>();
		dataBaseList = ygPublishMapper.findSimilarityPublishModelByProductId(new Long[] { productId });
		setData(dataBaseList, result, excludePublishId);
	}

	// 4首页推荐晒单
	private void similarityStep4(List<YgSimilarityPublishModel> result, Long excludePublishId) {
		List<YgSimilarityPublishModel> dataBaseList = new ArrayList<YgSimilarityPublishModel>();
		dataBaseList = ygPublishMapper.findSimilarityPublishTop10();
		setData(dataBaseList, result, excludePublishId);
	}

	@Override
	public int updateBatchChechStatus(String checkBy, String checkStatus, Long[] ids) {
		return ygPublishMapper.updateBatchChechStatus(checkBy, checkStatus, ids);
	}

	@Override
	public ResultSet<YgIndexModel> selectModel4Tag(QueryInfo queryInfo, String tag) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("tag", tag);
		List<YgIndexModel> list = ygPublishMapper.selectModel4Tag(queryInfo, params);
		int count = ygPublishMapper.selectModel4TagCount(params);
		ResultSet<YgIndexModel> resultSet = new ResultSet<YgIndexModel>(count, list);
		return resultSet;
	}

	/********************************** 以下是新接口 *****************************************/
	@Cacheable(cacheNames = "redis", key = "'publish:list_'+#queryInfo.start+'_'+#queryInfo.end")
	@Override
	public ResultSet<YgIndexModel> newSearchModel4Index(QueryInfo queryInfo) {
		List<YgIndexModel> models = ygPublishMapper.newSelectModel4Index(queryInfo, new HashMap<String, Object>());
		setComments(models);
		int count = ygPublishMapper.newSelectModel4IndexCount();
		ResultSet<YgIndexModel> resultSet = new ResultSet<YgIndexModel>(count, models);
		return resultSet;
	}

	private void setComments(List<YgIndexModel> models) {
		if (models.isEmpty()) {
			return;
		}
		Long[] pids = new Long[models.size()];
		for (int i = 0; i < models.size(); i++) {
			pids[i] = models.get(i).getPublishId();
		}
		List<YgIndexCommentModel> commentList = publishCommentMapper.findCommentByPublishIds(pids);

		for (YgIndexModel model : models) {

			for (YgIndexCommentModel comment : commentList) {
				if (model.getPublishId().equals(comment.getPublishId())) {
					if (model.getComments().size() < 3)
						model.getComments().add(comment);
				}
			}

		}
	}

	@Override
	public ResultSet<YgIndexModel> newSearchModel4User(QueryInfo queryInfo, Long userId) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("userId", userId);
		List<YgIndexModel> list = ygPublishMapper.newSelectModel4User(queryInfo, params);
		setComments(list);
		int count = ygPublishMapper.newSelectModel4UserCount(params);
		ResultSet<YgIndexModel> resultSet = new ResultSet<YgIndexModel>(count, list);
		return resultSet;
	}

	@Override
	public ResultSet<YgIndexModel> searchModel4Me(QueryInfo queryInfo, Long userId) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("userId", userId);
		params.put("needPermission", "false");
		List<YgIndexModel> list = ygPublishMapper.newSelectModel4User(queryInfo, params);
		setComments(list);
		int count = ygPublishMapper.newSelectModel4UserCount(params);
		ResultSet<YgIndexModel> resultSet = new ResultSet<YgIndexModel>(count, list);
		return resultSet;
	}

	@Override
	public ResultSet<YgIndexModel> newSearchModel4Praise(QueryInfo queryInfo, Long userId) {
		Long[] publishIds = commentService.findPublishIdsByUser(userId);
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("publishIds", publishIds);
		if (publishIds.length == 0) {
			return new ResultSet<YgIndexModel>();
		}
		params.put("excludeUserId", userId);
		int count = ygPublishMapper.newSelectModel4PublishCount(params);
		List<YgIndexModel> list = ygPublishMapper.newSelectModel4Publish(queryInfo, params);
		setComments(list);
		ResultSet<YgIndexModel> resultSet = new ResultSet<YgIndexModel>(count, list);
		return resultSet;
	}

	@Override
	public ResultSet<YgIndexModel> newSelectModel4Tag(QueryInfo queryInfo, String tag) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("tag", tag);
		List<YgIndexModel> list = ygPublishMapper.newSelectModel4Tag(queryInfo, params);
		setComments(list);
		int count = ygPublishMapper.newSelectModel4TagCount(params);
		ResultSet<YgIndexModel> resultSet = new ResultSet<YgIndexModel>(count, list);
		return resultSet;
	}

	@Override
	public int publishComment(Long publishId, String content, Long userId, Long receiverId) {
		YgPublishComment comment = new YgPublishComment();
		comment.setPublishId(publishId);
		comment.setUserId(userId);
		comment.setContent(content);
		comment.setAuditStatus(CheckStatus.Pass);
		comment.setCreateTime(new Date());
		comment.setPublishType(CommentType.Comment);
		Set<String> set = sensitivewordFilter.getSensitiveWord(content, 1);
		if (set.size() > 0) {
			comment.setAuditStatus(CheckStatus.Reject);
			comment.setCheckRemark("包含敏感词:" + set.toString());
			logger.debug("语句中包含敏感词的个数为：" + set.size() + "。包含：" + set);
		} else {
			publishCommentService.sendMessage(comment, receiverId);
		}
		return publishCommentMapper.insertSelective(comment);
	}

}
